
using System.Collections.Generic;
using Sinacor.Infra.UI.Common;
using Sinacor.Infra.UI.Authorization.Infra.Authorization.Policy;
using Sinacor.Infra.UI.Security.Services;
using System;
using Sinacor.Infra.UI.Authorization.Policy.CustomException;
using PSE.Framework.Common.Security.Services.Configuration;
namespace Sinacor.Infra.UI.Authorization.Policy.Communication
{
	public class PolicyLoader
    {

        public PolicyLoader()
        {

		}

        #region IPolicyProvider Members

        public List<Entity.Policy> GetPolicies(Entity.Policy policy)
        {
            try
            {
                Session.Session session = Session.SessionManager.GetInstance().GetCurrentSession();
                if (session != null)
                {
                    SessionInformation sessionInfo = session.GenerateSessionInformation();

                    if (sessionInfo != null)
                    {
                        using (ServiceInstance<IPolicy> si = new ServiceInstance<IPolicy>())
                        {
                            IPolicy service = si.TryGetInstance(sessionInfo, CriptographyLevelType.Basic);
                            Infra.Authorization.Policy.RetrievePoliciesRequest request = new RetrievePoliciesRequest();

                            Translator.PolicyResponseToPolicy translator = new Sinacor.Infra.UI.Authorization.Policy.Translator.PolicyResponseToPolicy();

                            request.PolicyId = policy.PolicyId;
                            request.PolicyName = policy.PolicyName;

                            Infra.Authorization.Policy.PolicyStatus? status;
                            Translator.Enum.PolicyStatusTranslator.Translate(policy.PolicyStatus, out status);
                            request.PolicyStatus = status;

                            Infra.Authorization.Policy.PolicyType? type;
                            Translator.Enum.PolicyTypeTranslator.Translate(policy.PolicyType, out type);
                            request.PolicyType = type;

                            return translator.TranslateToList(service.RetrievePolicies(request));
                        }
                    }
                    else
                    {
                        //caso n exista a session information, estourar erro informando
                        throw new NullReferenceException("SessionInformation is null.");
                    }
                }
                else
                {
                    //caso n exista a session, estourar erro informando
                    throw new NullReferenceException("Session is null.");
                }
            }
            catch (System.Exception ex)
            {
                throw new PolicyCommunicationException("An exception ocurred when to retrieve the policies. See the inner exceptions for more details.", ex);
            }
        }

        public Entity.Policy GetPolicy(Entity.Policy policy)
        {
            try
            {
                Session.Session session = Session.SessionManager.GetInstance().GetCurrentSession();
                if (session != null)
                {
                    SessionInformation sessionInfo = session.GenerateSessionInformation();

                    if (sessionInfo != null)
                    {
                        using (ServiceInstance<IPolicy> si = new ServiceInstance<IPolicy>())
                        {
                            IPolicy service = si.TryGetInstance(sessionInfo, CriptographyLevelType.Basic);
                            Infra.Authorization.Policy.RetrievePolicyRequest request = new RetrievePolicyRequest();

                            Translator.PolicyResponseToPolicy translator = new Sinacor.Infra.UI.Authorization.Policy.Translator.PolicyResponseToPolicy();

                            request.PolicyId = policy.PolicyId;

                            return translator.Translate(service.RetrievePolicy(request));
                        }
                    }
                    else
                    {
                        //caso n exista a session information, estourar erro informando
                        throw new NullReferenceException("SessionInformation is null.");
                    }
                }
                else
                {
                    //caso n exista a session, estourar erro informando
                    throw new NullReferenceException("Session is null.");
                }
            }
            catch (Exception ex)
            {
                throw new PolicyCommunicationException("An exception ocurred when to retrieve a policy. See the inner exceptions for more details.", ex);
            }
        }

        public Entity.Policy InsertPolicy(Entity.Policy policy)
        {
            try
            {
                Session.Session session = Session.SessionManager.GetInstance().GetCurrentSession();
                if (session != null)
                {
                    SessionInformation sessionInfo = session.GenerateSessionInformation();

                    if (sessionInfo != null)
                    {
                        using (ServiceInstance<IPolicy> si = new ServiceInstance<IPolicy>())
                        {
                            IPolicy service = si.TryGetInstance(sessionInfo, CriptographyLevelType.Basic);
                            Infra.Authorization.Policy.InsertPolicyRequest request = new InsertPolicyRequest();

                            Translator.PolicyResponseToPolicy translator = new Sinacor.Infra.UI.Authorization.Policy.Translator.PolicyResponseToPolicy();

                            request.PolicyName = policy.PolicyName;

                            Infra.Authorization.Policy.PolicyStatus? status;
                            Translator.Enum.PolicyStatusTranslator.Translate(policy.PolicyStatus, out status);
                            request.PolicyStatus = status;

                            Infra.Authorization.Policy.PolicyType? type;
                            Translator.Enum.PolicyTypeTranslator.Translate(policy.PolicyType, out type);
                            request.PolicyType = type;

                            return translator.Translate(service.InsertPolicy(request));
                        }
                    }
                    else
                    {
                        //caso n exista a session information, estourar erro informando
                        throw new NullReferenceException("SessionInformation is null.");
                    }
                }
                else
                {
                    //caso n exista a session, estourar erro informando
                    throw new NullReferenceException("Session is null.");
                }
            }
            catch (Exception ex)
            {
                throw new PolicyCommunicationException("An exception ocurred when to insert a policy. See the inner exceptions for more details.", ex);
            }
        }

        public void UpdatePolicy(Entity.Policy policy)
        {
            try
            {
                Session.Session session = Session.SessionManager.GetInstance().GetCurrentSession();
                if (session != null)
                {
                    SessionInformation sessionInfo = session.GenerateSessionInformation();

                    if (sessionInfo != null)
                    {
                        using (ServiceInstance<IPolicy> si = new ServiceInstance<IPolicy>())
                        {
                            IPolicy service = si.TryGetInstance(sessionInfo, CriptographyLevelType.Basic);
                            Infra.Authorization.Policy.UpdatePolicyRequest request = new UpdatePolicyRequest();

                            request.PolicyId = policy.PolicyId;
                            request.PolicyName = policy.PolicyName;

                            Infra.Authorization.Policy.PolicyStatus? status;
                            Translator.Enum.PolicyStatusTranslator.Translate(policy.PolicyStatus, out status);
                            request.PolicyStatus = status;

                            Infra.Authorization.Policy.PolicyType? type;
                            Translator.Enum.PolicyTypeTranslator.Translate(policy.PolicyType, out type);
                            request.PolicyType = type;

                            service.UpdatePolicy(request);
                        }
                    }
                    else
                    {
                        //caso n exista a session information, estourar erro informando
                        throw new NullReferenceException("SessionInformation is null.");
                    }
                }
                else
                {
                    //caso n exista a session, estourar erro informando
                    throw new NullReferenceException("Session is null.");
                }
            }
            catch (Exception ex)
            {
                throw new PolicyCommunicationException("An exception ocurred when to update a policy. See the inner exceptions for more details.", ex);
            }
        }

        public void DeletePolicy(Entity.Policy policy)
        {
            try
            {
                Session.Session session = Session.SessionManager.GetInstance().GetCurrentSession();
                if (session != null)
                {
                    SessionInformation sessionInfo = session.GenerateSessionInformation();

                    if (sessionInfo != null)
                    {
                        using (ServiceInstance<IPolicy> si = new ServiceInstance<IPolicy>())
                        {
                            IPolicy service = si.TryGetInstance(sessionInfo, CriptographyLevelType.Basic);
                            Infra.Authorization.Policy.DeletePolicyRequest request = new DeletePolicyRequest();

                            request.PolicyId = policy.PolicyId;

                            service.DeletePolicy(request);
                        }
                    }
                    else
                    {
                        //caso n exista a session information, estourar erro informando
                        throw new NullReferenceException("SessionInformation is null.");
                    }
                }
                else
                {
                    //caso n exista a session, estourar erro informando
                    throw new NullReferenceException("Session is null.");
                }
            }
            catch (Exception ex)
            {
                throw new PolicyCommunicationException("An exception ocurred when to delete a policy. See the inner exceptions for more details.", ex);
            }
        }

        #endregion
    }
}